// Decompiled by DJ v3.11.11.95 Copyright 2009 Atanas Neshkov  Date: 2/1/2010 3:10:09 AM
// Home Page: http://members.fortunecity.com/neshkov/dj.html  http://www.neshkov.com/dj.html - Check often for new version!
// Decompiler options: packimports(3) 
// Source File Name:   OthelloFrame.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class OthelloFrame extends JFrame
{
    private class BoardPanel extends JPanel
        implements OthelloBoardChangeListener
    {
        private class BoardPanelMouseAdapter
            implements MouseListener, MouseMotionListener
        {

            public void mouseClicked(MouseEvent mouseevent)
            {
                if(currentState == null)
                {
                    startNewGame();
                } else
                {
                    if(currentState.isBlackTurn() && blackAI != null || !currentState.isBlackTurn() && whiteAI != null)
                        return;
                    final int row = getRow(mouseevent);
                    final int col = getCol(mouseevent);
                    if(validMovePosition(row, col))
                    {
                        Thread thread = new Thread(new Runnable() {

                            public void run()
                            {
                                currentState.makeMove(row, col);
                            }

                            final int val$row;
                            final int val$col;
                            final BoardPanelMouseAdapter this$2;

//                    
//                    {
//                        this$2 = BoardPanelMouseAdapter.this;
//                          super();
//                        row = i;
//                        col = j;

//                    }
                        }
);
                        thread.setDaemon(true);
                        thread.start();
                    }
                }
            }

            public void mouseEntered(MouseEvent mouseevent)
            {
                if(currentState == null)
                    setCursor(Cursor.getPredefinedCursor(12));
            }

            public void mouseExited(MouseEvent mouseevent)
            {
                if(currentState == null)
                    setCursor(Cursor.getPredefinedCursor(0));
            }

            public void mouseMoved(MouseEvent mouseevent)
            {
                if(currentState == null)
                    return;
                if(currentState.isBlackTurn() && blackAI == null || !currentState.isBlackTurn() && whiteAI == null)
                {
                    if(validMovePosition(getRow(mouseevent), getCol(mouseevent)))
                        setCursor(Cursor.getPredefinedCursor(12));
                    else
                        setCursor(Cursor.getPredefinedCursor(0));
                } else
                {
                    setCursor(Cursor.getPredefinedCursor(0));
                }
            }

            private int getRow(MouseEvent mouseevent)
            {
                int i = mouseevent.getY() - topY;
                int j = i / yStep;
                int k = i % yStep;
                if(j >= 0 && j < 8 && k >= 5 && yStep - k >= 5)
                    return j;
                else
                    return -1;
            }

            private int getCol(MouseEvent mouseevent)
            {
                int i = mouseevent.getX() - leftX;
                int j = i / xStep;
                int k = i & xStep;
                if(j >= 0 && j < 8 && k >= 5 && xStep - k >= 5)
                    return j;
                else
                    return -1;
            }

            private boolean validMovePosition(int i, int j)
            {
                return i != -1 && j != -1 && currentState.isValidMove(i, j);
            }

            public void mouseDragged(MouseEvent mouseevent)
            {
            }

            public void mousePressed(MouseEvent mouseevent)
            {
            }

            public void mouseReleased(MouseEvent mouseevent)
            {
            }

            final BoardPanel this$1;

            private BoardPanelMouseAdapter()
            {
            	super();
                this$1 = BoardPanel.this;
                
            }

        }


        public void paint(Graphics g)
        {
            super.paint(g);
            Graphics2D graphics2d = (Graphics2D)g;
            graphics2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            if(currentState == null)
            {
                graphics2d.setFont(new Font("SansSerif", 1, 14));
                graphics2d.setColor(Color.WHITE);
                graphics2d.drawString("Click here to start game", 150, 210);
            } else
            {
                topLabel.setText((new StringBuilder()).append("Black: ").append(currentState.getBlackScore()).append("   White: ").append(currentState.getWhiteScore()).toString());
                if(currentState.gameIsOver())
                {
                    int i = currentState.getBlackScore();
                    int i1 = currentState.getWhiteScore();
                    String s1;
                    if(i > i1)
                        s1 = "Black wins!";
                    else
                    if(i < i1)
                        s1 = "White wins!";
                    else
                        s1 = " it's a draw!";
                    bottomLabel.setText((new StringBuilder()).append("Game over; ").append(s1).append("  (Click here to start a new game.)").toString());
                } else
                {
                    String s;
                    if(currentState.isBlackTurn())
                        s = blackAI != null ? "Black AI is considering its move" : "Black's turn";
                    else
                        s = whiteAI != null ? "White AI is considering its move" : "White's turn";
                    bottomLabel.setText((new StringBuilder()).append("Game in progress; ").append(s).toString());
                }
                graphics2d.setColor(Color.BLACK);
                for(int j = 0; j <= 8; j++)
                    graphics2d.drawLine(leftX, topY + j * yStep, rightX, topY + j * yStep);

                for(int k = 0; k <= 8; k++)
                    graphics2d.drawLine(leftX + k * xStep, topY, leftX + k * xStep, bottomY);

                for(int l = 0; l < 8; l++)
                {
                    for(int j1 = 0; j1 < 8; j1++)
                    {
                        OthelloCell othellocell = currentState.getCell(l, j1);
                        if(othellocell == OthelloCell.WHITE)
                            graphics2d.setColor(Color.WHITE);
                        else
                        if(othellocell == OthelloCell.BLACK)
                            graphics2d.setColor(Color.BLACK);
                        if(othellocell != OthelloCell.NONE)
                            graphics2d.fillOval(leftX + j1 * xStep + 5, topY + l * yStep + 5, xStep - 10, yStep - 10);
                    }

                }

            }
        }

        public void boardChanged(OthelloGameState othellogamestate)
        {
            currentState = othellogamestate;
            if(lastAnimateTiles)
            {
                EventQueue.invokeLater(new Runnable() {

                    public void run()
                    {
                        repaint();
                    }

                    final BoardPanel this$1;

                
                {
                    this$1 = BoardPanel.this;
                    super();
                }
                }
);
                try
                {
                    Thread.sleep(400L);
                }
                catch(InterruptedException interruptedexception) { }
            }
        }

        public void newTurn(OthelloGameState othellogamestate)
        {
            currentState = othellogamestate;
            EventQueue.invokeLater(new Runnable() {

                public void run()
                {
                    repaint();
                }

                final BoardPanel this$1;

                
                {
                    this$1 = BoardPanel.this;
                    super();
                }
            }
);
            if(!currentState.gameIsOver())
            {
                Thread thread = new Thread(new Runnable() {

                    public void run()
                    {
                        if(blackAI != null && currentState.isBlackTurn())
                            aiMove(blackAI);
                        else
                        if(whiteAI != null && !currentState.isBlackTurn())
                            aiMove(whiteAI);
                    }

                    private void aiMove(OthelloAI othelloai)
                    {
                        try
                        {
                            OthelloMove othellomove = othelloai.chooseMove(currentState.clone());
                            if(othellomove == null)
                                JOptionPane.showMessageDialog(_fld0, "ERROR: AI returned null OthelloMove!\nchooseMove() is not permitted to return null.", "Null OthelloMove", 0);
                            else
                                currentState.makeMove(othellomove.getRow(), othellomove.getColumn());
                        }
                        catch(Exception exception)
                        {
                            exception.printStackTrace();
                            JOptionPane.showMessageDialog(_fld0, "ERROR: AI threw an exception\nSee console for more information", "AI Exception", 0);
                        }
                    }

                    final BoardPanel this$1;

                
                {
                    this$1 = BoardPanel.this;
                    super();
                }
                }
);
                thread.setDaemon(true);
                thread.start();
            }
        }

        private void startNewGame()
        {
            OthelloNewGameDialog othellonewgamedialog = new OthelloNewGameDialog(OthelloFrame.this, lastBlackIsHuman, lastWhiteIsHuman, lastAnimateTiles);
            othellonewgamedialog.setLocationRelativeTo(this);
            othellonewgamedialog.setVisible(true);
            if(othellonewgamedialog.okPressed())
            {
                lastBlackIsHuman = othellonewgamedialog.blackIsHuman();
                if(lastBlackIsHuman)
                    blackAI = null;
                else
                    blackAI = createAI();
                lastWhiteIsHuman = othellonewgamedialog.whiteIsHuman();
                if(lastWhiteIsHuman)
                    whiteAI = null;
                else
                    whiteAI = createAI();
                lastAnimateTiles = othellonewgamedialog.animateTiles();
                OthelloGameStateImpl othellogamestateimpl = new OthelloGameStateImpl();
                othellogamestateimpl.addBoardChangeListener(this);
                currentState = othellogamestateimpl;
                repaint();
                newTurn(currentState);
            }
        }

        private void bottomLabelClicked()
        {
            if(currentState != null && currentState.gameIsOver())
                startNewGame();
        }

        private OthelloAI createAI()
        {
            OthelloAI othelloai = (new OthelloAIFactory()).createOthelloAI();
            if(othelloai == null)
                JOptionPane.showMessageDialog(OthelloFrame.this, "Your OthelloAIFactory().createOthelloAI() method returned null.\nBe sure to write the line of code into that method that creates\nan object of your AI class.", "OthelloAIFactory not implemented", 0);
            return othelloai;
        }

        private int leftX;
        private int rightX;
        private int topY;
        private int bottomY;
        private int xStep;
        private int yStep;
        private OthelloGameState currentState;
        private OthelloAI blackAI;
        private OthelloAI whiteAI;
        private boolean lastBlackIsHuman;
        private boolean lastWhiteIsHuman;
        private boolean lastAnimateTiles;
        final OthelloFrame this$0;










        public BoardPanel(int i, int j, int k, int l, int i1, int j1)
        {
            this$0 = OthelloFrame.this;
            super();
            leftX = i;
            rightX = j;
            topY = k;
            bottomY = l;
            xStep = i1;
            yStep = j1;
            setBackground(new Color(0, 128, 0));
            currentState = null;
            blackAI = null;
            whiteAI = null;
            enableEvents(16L);
            addMouseListener(new BoardPanelMouseAdapter());
            addMouseMotionListener(new BoardPanelMouseAdapter());
            lastBlackIsHuman = true;
            lastWhiteIsHuman = true;
            lastAnimateTiles = true;
        }
    }


    public OthelloFrame()
    {
        super("ICS 23 / CSE 23 Project #2: Black and White");
        configureUI();
        buildUI();
    }

    private void configureUI()
    {
        Dimension dimension = new Dimension(500, 500);
        getContentPane().setMinimumSize(dimension);
        getContentPane().setPreferredSize(dimension);
        getContentPane().setBackground(Color.BLACK);
        setDefaultCloseOperation(2);
        setLayout(null);
        setResizable(false);
        pack();
    }

    private void buildUI()
    {
        topLabel = new JLabel("No game in progress");
        topLabel.setFont(new Font("SansSerif", 1, 13));
        topLabel.setForeground(Color.WHITE);
        topLabel.setOpaque(false);
        topLabel.setHorizontalAlignment(0);
        topLabel.setBounds(10, 10, 480, 15);
        getContentPane().add(topLabel);
        byte byte0 = 10;
        char c = '\u01C2';
        byte byte1 = 10;
        char c1 = '\u019A';
        byte byte2 = 55;
        byte byte3 = 50;
        boardPanel = new BoardPanel(byte0, c, byte1, c1, byte2, byte3);
        boardPanel.setBounds(20, 40, 460, 420);
        getContentPane().add(boardPanel);
        bottomLabel = new JLabel("");
        bottomLabel.setFont(new Font("SansSerif", 1, 13));
        bottomLabel.setForeground(Color.WHITE);
        bottomLabel.setOpaque(false);
        bottomLabel.setHorizontalAlignment(0);
        bottomLabel.setBounds(10, 475, 475, 15);
        bottomLabel.addMouseListener(new MouseAdapter() {

            public void mouseClicked(MouseEvent mouseevent)
            {
                boardPanel.bottomLabelClicked();
            }

            final OthelloFrame this$0;

            
            {
            	super();
                this$0 = OthelloFrame.this;
                
            }
        }
);
        getContentPane().add(bottomLabel);
    }

    private static final String NO_SCORE = "No game in progress";
    private static final String CLICK_HERE_TO_START_GAME = "Click here to start game";
    private JLabel topLabel;
    private BoardPanel boardPanel;
    private JLabel bottomLabel;



}
